package com.tvunetworks.center.user.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.tvunetworks.center.common.exception.RpcException;
import com.tvunetworks.center.common.model.GetTpcFeatureEnableParam;
import com.tvunetworks.center.common.model.LoginUser;
import com.tvunetworks.center.common.model.dto.GeoDetail;
import com.tvunetworks.center.common.util.*;
import com.tvunetworks.center.user.model.param.CreateUserParam;
import com.tvunetworks.center.user.service.UserHttpService;
import com.tvunetworks.center.user.util.GZipUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: tvucc-user
 * @description: 对外Http请求
 * @author lebronchen
 * @create: 2019-03-05 17:17
 **/
@Service
@Slf4j
public class UserHttpServiceImpl implements UserHttpService {

    @Value("${serviceNameInAuthorizationService}")
    private String serviceNameInAuthorizationService;
    @Value("${registerVCode}")
    private String registerVCode;
    @Value("${superRactivationCode}")
    private String superRactivationCode;
    @Value("${geo.whiteListKey}")
    private String geoWhiteListKey;

    @Value("${userService.url.GetInfoJSON}")
    private String GetInfoJSON;
    @Value("${userService.url.LogOut}")
    private String LogOut;
    @Value("${userService.url.ListAccessableService}")
    private String ListAccessableService;
    @Value("${userService.url.GetRoleByEmail}")
    private String GetRoleByEmail;
    @Value("${userService.url.GetUserId}")
    private String GetUserId;
    @Value("${userService.url.CreateUserForOtherService}")
    private String CreateUserForOtherService;
    @Value("${userService.url.AddAndRemoveUserService}")
    private String AddAndRemoveUserService;
    @Value("${userService.url.LoginJSON}")
    private String LoginJSON;
    @Value("${geoService.url.GetAddressLocationByLatAndLngServlet}")
    private String GetAddressLocationByLatAndLngServlet;
    @Value("${geoService.url.GetGeoLocationByAddressServlet}")
    private String GetGeoLocationByAddressServlet;
    @Value("${geoService.url.getLatLngAndAddressByMultiIpServlet}")
    private String getLatLngAndAddressByMultiIpServlet;
    @Value("${tpds.url.TransferJsonServlet}")
    private String TransferJsonServlet;
    @Value("${gcs.url.addPairForGM}")
    private String addPairForGM;
    @Value("${gcs.url.removePairForGM}")
    private String removePairForGM;
    @Value("${gcs.url.getGridSourceByRidForGM}")
    private String getGridSourceByRidForGM;
    @Value("${tpc.url.getFeatureStatusInfo}")
    private String getFeatureStatusInfo;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public Result<LoginUser> userserviceGetUserInfo(String session) throws IOException {
        String url = GetInfoJSON + "?session=" + session;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserserviceGetUserInfo :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserserviceGetUserInfo failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice http connect error");
        }
        log.info("RPC gainMessageJSON :result:{}", responseEntity);
        String body = responseEntity.getBody();
        JsonNode jsonNode = MyUtil.MAPPER.readTree(body);
        String errorCode = jsonNode.get("errorCode").asText();
        if (!StringUtils.equals(ResultUtil.SUCCESS, errorCode)) {
            return ResultUtil.error("102", "Session Invalid");
        }
        LoginUser userserviceUser = MyUtil.MAPPER_NON_NULL.readValue(MyUtil.MAPPER.writeValueAsBytes(jsonNode.get("user")), LoginUser.class);
        return ResultUtil.success(userserviceUser);
    }

    @Override
    public Result<Void> userserviceLogout(String session) throws IOException {
        String url = LogOut + "?session=" + session;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserserviceLogout :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserserviceLogout failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice http connect error");
        }
        log.info("RPC UserserviceLogout :result:{}", responseEntity);
        String body = responseEntity.getBody();
        JsonNode jsonNode = MyUtil.MAPPER.readTree(body);
        String errorCode = jsonNode.get("errorCode").asText();
        if (!StringUtils.equals(ResultUtil.SUCCESS, errorCode)) {
            log.error("RPC UserserviceLogout error:result:{}", responseEntity);
            return ResultUtil.error("102", "Session Invalid");
        }
        return ResultUtil.success();
    }

    @Override
    public Result<Boolean> userserviceCheckServiceAccessable(String session) throws IOException {
        return this.userserviceCheckServiceAccessable(session, serviceNameInAuthorizationService);
    }

    @Override
    public Result<Boolean> userserviceCheckServiceAccessable(String session, String serverName) throws IOException {
        String url = ListAccessableService + "?session=" + session;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserserviceCheckServiceAccessable :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserserviceCheckServiceAccessable failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice http connect error");
        }
        log.info("RPC UserserviceCheckServiceAccessable :result:{}", responseEntity);
        String body = responseEntity.getBody();
        JsonNode jsonNode = MyUtil.MAPPER.readTree(body);
        String errorCode = jsonNode.get("errorCode").asText();
        if (!StringUtils.equals(ResultUtil.SUCCESS, errorCode)) {
            log.error("RPC UserserviceCheckServiceAccessable Logout error:result:{}", responseEntity);
            return ResultUtil.error("102", "Session Invalid");
        }
        JsonNode serviceList = jsonNode.get("serviceList");
        boolean authSuccess = false;
        for (JsonNode service : serviceList) {
            String serviceName = service.get("serviceName").asText();
            if (!serverName.equals(serviceName)) {
                continue;
            }
            authSuccess = true;
            break;
        }
        return ResultUtil.success(authSuccess);
    }

    @Override
    public Result<List<String>> getTpcFeatureEnable(GetTpcFeatureEnableParam param) throws IOException {
        String featureStatusInfoDetail = MyUtil.MAPPER.writeValueAsString(param);
        String url = getFeatureStatusInfo  + "?featureStatusInfoDetail={featureStatusInfoDetail}";
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC TPC GetFeatureStatusInfo :url:{}, featureStatusInfoDetail:{}", url, featureStatusInfoDetail);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class, featureStatusInfoDetail);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC TPC GetFeatureStatusInfo failed:result:{}", responseEntity);
            return ResultUtil.error("101", "TPC http connect error");
        }
        log.info("RPC TPC GetFeatureStatusInfo :result:{}", responseEntity);
        String body = responseEntity.getBody();
        Map<String,Map<String, Map>> map = JsonUtil.toObject(body, Map.class);
        HashMap<String,Map<String,Map>> peerFeatureMap = (HashMap)map.get("peerFeatureMap");

        List<String> resultList = new ArrayList<>();
        peerFeatureMap.forEach((x,y) -> {
            if ("0001".equals(y.get("paraType"))) {
                resultList.add(x);
            }
            System.out.println( y.get("paraType") );
        });
        return ResultUtil.success(resultList);
    }

    @Override
    public Result<String> getUserRole(String email, String token) {
        String url = GetRoleByEmail + "?session=" + token + "&email=" + email;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserserviceGetUserRole :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserserviceGetUserRole failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice GetUserRole http connect error");
        }
        log.info("RPC UserserviceGetUserRole :result:{}", responseEntity);
        String body = responseEntity.getBody();
        if(body!=null){
            try {
                Map<String, String> result = JsonUtil.toObject(body, Map.class);
                String errorCode = result.get("ErrorCode");
                if (!StringUtils.equals(ResultUtil.SUCCESS, errorCode)) {
                    log.error("RPC GetUserRole failed:result:{}", responseEntity);
                }

                return ResultUtil.success(result.get("Role"));

            } catch (IOException e) {
                log.error("解析出现异常---》" + body);
                return ResultUtil.error("103", "Parse xml failed");
            }
       /*     String role = parseUserRole(body);
            if (StringUtils.equalsIgnoreCase("-1", role)) {
                log.error("RPC GetUserRole failed:result:{}", responseEntity);
                return ResultUtil.error("102", "Userservice GetUserRole failed");
            }
            return ResultUtil.success(role);*/
        }
       return null;
    }

    @Override
    public Result<String> getUserId(String session, String email) {
        String url = GetUserId + "?session=" + session + "&email=" + email;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC Userservice GetUserId :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);

        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC Userservice GetUserId failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice http connect error");
        }
        log.info("RPC Userservice GetUserId :result:{}", responseEntity);
        String body = responseEntity.getBody();
        try {
            Map<String, String> result = JsonUtil.toObject(body,Map.class);
            String errorCode = result.get("ErrorCode");
            if (!StringUtils.equals(ResultUtil.SUCCESS,errorCode)){
                return ResultUtil.error("102", "User not exist");
            }

                return ResultUtil.success(result.get("Id"));

        } catch (IOException e) {
            log.error("解析出现异常---》" + body);
            return ResultUtil.error("103", "Parse xml failed");
        }

        /*try {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=factory.newDocumentBuilder();
            if(builder!=null){
                Document doc = builder.parse(new ByteArrayInputStream(body.getBytes("UTF-8")));
                Node root = doc.getElementsByTagName("Root").item(0);
                if (!StringUtils.equals(ResultUtil.SUCCESS, root.getAttributes().getNamedItem("ErrorCode").getNodeValue())) {
                    return ResultUtil.error("102", "User not exist");
                }
                String userId = root.getFirstChild().getTextContent();
                return ResultUtil.success(userId);
            }
           return  null;
        } catch (ParserConfigurationException e) {
            log.error("解析出现异常---》" + body);
            return ResultUtil.error("103", "Parse xml failed");
        } catch (SAXException saxException) {
                saxException.printStackTrace();
            return ResultUtil.error("103", "Parse xml failed");
        } catch (IOException ioException) {
            ioException.printStackTrace();
            return ResultUtil.error("103", "Parse xml failed");
        }*/
    }

    @Override
    public Result<String> userServiceCreateUser(CreateUserParam param) {
        StringBuilder buffer = new StringBuilder(CreateUserForOtherService);
        buffer.append("?session=").append(param.getSession())
                .append("&userName=").append(param.getEmail())
                .append("&email=").append(param.getEmail())
                .append("&password=").append(PasswordEncodeUtil.encode(param.getPassword()))
                .append("&VCode=").append(registerVCode)
                .append("&code=").append(superRactivationCode)
                .append("&serviceNames=");
        if (StringUtils.equals("1", param.getActive())) {
            buffer.append(serviceNameInAuthorizationService);
        }
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserService CreateUser :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserServiceCreateUser failed:result:{}", responseEntity);
            return ResultUtil.error("101", "Userservice http connect error");
        }
        log.info("RPC UserService CreateUser :result:{}", responseEntity);
        String body = responseEntity.getBody();
        try {
            Map<String, String> result = JsonUtil.toObject(body,Map.class);
            String errorCode = result.get("errorCode");
            if (!StringUtils.equals(ResultUtil.SUCCESS,errorCode)){
                return ResultUtil.error("102", "Create user failed"+"~~~" +result.get("errorInfo"));
            }

            return ResultUtil.success();

        } catch (IOException e) {
            log.error("解析出现异常---》" + body);
            return ResultUtil.error("103", "Parse xml failed");
        }
     /*  try {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
            DocumentBuilder builder=factory.newDocumentBuilder();
            if (builder!=null){
                Document doc = builder.parse(new ByteArrayInputStream(body.getBytes("UTF-8")));
                Node root = doc.getElementsByTagName("Root").item(0);
                if (!StringUtils.equals("0x0", root.getAttributes().getNamedItem("ErrorCode").getNodeValue())) {
                    return ResultUtil.error("102", "Create user failed", root.getAttributes().getNamedItem("ErrorInfo").getNodeValue());
                }
                return ResultUtil.success();
            }
                return null;
         } catch (ParserConfigurationException e) {
                 log.error("解析出现异常---》" + body);
                 return ResultUtil.error("103", "Parse xml failed");
         }catch (SAXException saxException) {
              saxException.printStackTrace();
                return ResultUtil.error("103", "Parse xml failed");
         } catch (IOException ioException) {
               ioException.printStackTrace();
                 return ResultUtil.error("103", "Parse xml failed");
         }*/
    }

    @Override
    public Result<String> activateAndDisActivateUser(String id, String active) {
        StringBuilder buffer = new StringBuilder(AddAndRemoveUserService);
        buffer.append("?id=").append(id)
                .append("&active=").append(active)
                .append("&serviceNames=").append(serviceNameInAuthorizationService);
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserService ActivateAndDisActivateUser :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserService ActivateAndDisActivateUser failed:result:{}", responseEntity);
            throw new RpcException("UserService ActivateAndDisActivateUser failed");
        }
        log.info("RPC UserService ActivateAndDisActivateUser :result:{}", responseEntity);

        String body = responseEntity.getBody();

        try {
            Map<String, String> result = JsonUtil.toObject(body,Map.class);
            String errorCode = result.get("errorCode");
            if (!StringUtils.equals(ResultUtil.SUCCESS,errorCode)){
                return ResultUtil.error("102", "Set active failed"+"~~~"+result.get("errorInfo"));
            }

            return ResultUtil.success();

        } catch (Exception e) {
            log.error("解析出现异常---》" + body);
            return ResultUtil.error("103", "Parse xml failed");
        }
       /* try {
            DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        DocumentBuilder builder= null;

            builder = factory.newDocumentBuilder();

        if (body!=null){
            Document doc = null;

                doc = builder.parse(new ByteArrayInputStream(body.getBytes("UTF-8")));

            Node root = doc.getElementsByTagName("Root").item(0);
                if (!StringUtils.equals("0x0", root.getAttributes().getNamedItem("ErrorCode").getNodeValue())) {
                    return ResultUtil.error("102", "Set active failed", root.getAttributes().getNamedItem("ErrorInfo").getNodeValue());
                }
            }
            return ResultUtil.success();
        } catch (ParserConfigurationException e) {
            log.error("解析出现异常---》" + body);
            return ResultUtil.error("103", "Parse xml failed");
        }catch (SAXException saxException) {
        saxException.printStackTrace();
            return ResultUtil.error("103", "Parse xml failed");
        } catch (IOException ioException) {
        ioException.printStackTrace();
            return ResultUtil.error("103", "Parse xml failed");
        }*/

    }

    @Override
    public Result<String> getGeoNameByLocation(String location) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> param = new HashMap<>();
        param.put("location", location);
        param.put("whiteListKey", geoWhiteListKey);

        HttpEntity httpEntity = new HttpEntity(param, httpHeaders);
        String url = GetAddressLocationByLatAndLngServlet;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC GeoService GetGeoNameByLocation :url:{} param:{}", url, param);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GeoService GetGeoNameByLocation failed:result:{}", responseEntity);
            return ResultUtil.error("101", "GeoService http connect error");
        }
        String body = responseEntity.getBody();
        if (StringUtils.isBlank(body)) {
            log.error("RPC GeoService GetGeoNameByLocation null result param:[{}] result:[{}]", param, responseEntity);
            return ResultUtil.error("103", "Null result");
        }
        JsonNode jsonNode = null;
        try {
            jsonNode = MyUtil.MAPPER.readTree(body);
        } catch (IOException e) {
            log.error(e.toString(), e);
            return ResultUtil.error("104", "GeoService result error");
        }
        if (!jsonNode.has("data")) {
            log.error("GeoService GetGeoNameByLocation location:[{}] result:[{}]", location, body);
            return ResultUtil.error("105", "GeoService result error");
        }
        JsonNode jsonTree = jsonNode.get("data");

        try {
            if (!jsonTree.has(location)) {
                log.error("GeoService GetGeoNameByLocation location:[{}] result:[{}]", location, body);
                return ResultUtil.error("106", "GeoService result error");
            }
        } catch (Exception e) {
            log.error("GeoService GetGeoNameByLocation location:[{}] result:[{}]", location, body);
            return ResultUtil.error("107", "GeoService result error");
        }
        String result = jsonTree.get(location).asText();
        return ResultUtil.success(result);
    }

    @Override
    public Result<GeoDetail> getGeoNameByIp(String ip) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> param = new HashMap<>();
        param.put("ip", ip);
        param.put("whiteListKey", geoWhiteListKey);

        HttpEntity httpEntity = new HttpEntity(param, httpHeaders);
        String url = getLatLngAndAddressByMultiIpServlet;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.error("RPC GeoService GetGeoNameByIp :url:{} param:{}", url, param);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GeoService GetGeoNameByIp failed:result:{}", responseEntity);
            return ResultUtil.error("101", "GeoService http connect error");
        }
        String body = responseEntity.getBody();
        if (StringUtils.isBlank(body)) {
            log.error("RPC GeoService GetGeoNameByIp null result param:[{}] result:[{}]", param, responseEntity);
            return ResultUtil.error("103", "Null result");
        }
        JsonNode jsonNode = null;
        try {
            jsonNode = MyUtil.MAPPER.readTree(body);
        } catch (IOException e) {
            log.error(e.toString(), e);
            return null;
        }
        if (!jsonNode.has("data")) {
            log.error("GeoService GetGeoNameByIp ip:[{}] result:[{}]", ip, body);
            return null;
        }
        JsonNode jsonTree = jsonNode.get("data");
        if (jsonTree.size() > 0) {
            GeoDetail result = null;
            try {
                JsonNode obj = jsonTree.get(0);
                result = JsonUtil.convertValue(obj, GeoDetail.class);
            } catch (Exception e) {
                log.error("getGeoNameByIp Exception"+e.getMessage());
                log.error("getGeoNameByIp body ===="+body);

                log.error("msg:{},e:{}",e.getMessage(),e);
            }
            return ResultUtil.success(result);
        } else {
            return ResultUtil.error("104", "Null result");
        }

    }

    @Override
    public Result<String> getGetGeoLocationByAddress(String param) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> requestParam = new HashMap<>();
        String addressEncoder = null;
        try {
            addressEncoder = URLEncoder.encode(param, "utf-8");
        } catch (UnsupportedEncodingException e) {
            log.error(e.toString(), e);
            return ResultUtil.error("102", "Param encoder to utf-8 error");
        }

        requestParam.put("whiteListKey", geoWhiteListKey);
        requestParam.put("address", addressEncoder);

        HttpEntity httpEntity = new HttpEntity(requestParam, httpHeaders);
        String url = GetGeoLocationByAddressServlet;
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC GeoService GetGetGeoLocationByAddress :url:{} param:{}", url, requestParam);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, httpEntity, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GeoService GetGetGeoLocationByAddress failed:result:{}", responseEntity);
            return ResultUtil.error("101", "GeoService http connect error");
        }
        String body = responseEntity.getBody();
        if (StringUtils.isBlank(body)) {
            log.error("RPC GeoService GetGetGeoLocationByAddress null result param:[{}] result:[{}]", param, responseEntity);
            return ResultUtil.error("103", "Null result");
        }
        JsonNode jsonNode = null;
        try {
            jsonNode = MyUtil.MAPPER.readTree(body);
        } catch (IOException e) {
            log.error(e.toString(), e);
            return ResultUtil.error("104", "Parse result error", body);
        }
        if (!jsonNode.has("data")) {
            log.error("GeoService GetGetGeoLocationByAddress param:[{}] result:[{}]", param, body);
            return ResultUtil.error("105", "Result error", body);
        }
        String result = null;
        JsonNode data = jsonNode.get("data");
        if (data.has(param)) {
            result = data.get(param).asText();
        }
        return ResultUtil.success(result);
    }

    @Override
    public Result<String> sendGeoToTpds(String peerId, String latitude, String longitude) {
        Map<String, Object> gpsItem = new HashMap<>();
        gpsItem.put("latitude", latitude);
        gpsItem.put("longitude", longitude);
        gpsItem.put("accuracy", "0");
        gpsItem.put("timestamp", System.currentTimeMillis() + 34536000000L);

        // set gpsnocontainwifi3g list
        List<Map<String, Object>> gpsnocontainwifi3g = new ArrayList<Map<String, Object>>();
        gpsnocontainwifi3g.add(gpsItem);

        // interfaceType JSON param
        Map<String, Object> gpsResult = new HashMap<>();
        gpsResult.put("timesec", System.currentTimeMillis());
        gpsResult.put("msgv", "1.0");
        gpsResult.put("peerId", peerId.toUpperCase());
        gpsResult.put("gps", gpsnocontainwifi3g);

        // set header map param
        Map<String, String> headParams = new HashMap<>();
        headParams.put("peerid", peerId.toUpperCase());
        headParams.put("timestamp", String.valueOf(System.currentTimeMillis()));
        headParams.put("interfacetype", "GPSJson");
        headParams.put("accept-encoding", "gzip, deflate");

        HttpURLConnection con = null;
        OutputStream os = null;
        URL url;
        try {
            String requestUrl = TransferJsonServlet;
            if (!requestUrl.startsWith("http")) {
                requestUrl = "http://" + requestUrl;
            }
            url = new URL(requestUrl);
            con = (HttpURLConnection) url.openConnection();
            con.setReadTimeout(30 * 1000); // 缓存的最长时间
            con.setDoInput(true);// 允许输入
            con.setDoOutput(true);// 允许输出
            con.setUseCaches(false); // 不允许使用缓存
            con.setRequestMethod("POST");
            con.setRequestProperty("Charsert", "UTF-8");
            con.setRequestProperty("Content-Type", "text/html");
            if(headParams!=null){
                for(Map.Entry<String, String> entry: headParams.entrySet()){
                    con.setRequestProperty(entry.getKey(),entry.getValue());
                }
            }

            con.setConnectTimeout(10000);
            con.setReadTimeout(10000);
            con.connect();
            os = con.getOutputStream();
//            JSONObject obj = new JSONObject();
//            if ( gpsResult != null && gpsResult.size() > 0 ) {
//                Set<String> keySet = gpsResult.keySet();
//                for (String key : keySet) {
//                    obj.element(key, gpsResult.get(key));
//                }
//            }
            String gzip = GZipUtil.compress(JsonUtil.toJsonStr(gpsResult));
            os.write(gzip.getBytes("ISO-8859-1"));
            os.flush();
        } catch (Exception e) {
            log.error(e.toString(),e);
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error(e.toString(), e);
                }
            }
            if (con != null) {
                con.disconnect();
            }
        }
        return ResultUtil.success();
    }

    @Override
    public Result<String> getSession(String email, String password) {
        StringBuilder buffer = new StringBuilder(LoginJSON);
        buffer.append("?email=").append(email)
                .append("&pwd=").append(password);
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC UserService GetSession :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC UserService GetSession failed:result:{}", responseEntity);
            throw new RpcException("UserService GetSession failed");
        }
        log.info("RPC UserService GetSession :result:{}", responseEntity);

        String body = responseEntity.getBody();


        HashMap<String, String> map = null;
        try {
            map = JsonUtil.toObject(body, HashMap.class);
        } catch (IOException e) {
            log.error("GetSession parse json result failed email:[{}] password:[{}] body:[{}]", email, password, body);
            return ResultUtil.error("104", "Parse xml failed");
        }
        String errorCode = map.get("errorCode");
        if (StringUtils.isBlank(errorCode)) {
            log.error("GetSession failed errorCode is null email:[{}] password:[{}] body:[{}]", email, password, body);
            return ResultUtil.error("101", "GetSession result not exist errorCode", body);
        }
        if (!StringUtils.equalsIgnoreCase("0x0", errorCode)) {
            log.error("GetSession failed errorCode != 0x0 email:[{}] password:[{}] body:[{}]", email, password, body);
            return ResultUtil.error("102", "GetSession failed", body);
        }
        String session = map.get("session");
        if (StringUtils.isBlank(session)) {
            log.error("GetSession failed session is null email:[{}] password:[{}] body:[{}]", email, password, body);
            return ResultUtil.error("103", "GetSession session null", body);
        }
        return ResultUtil.success(session);

    }

    @Override
    public Result<String> addPairFromGCS(String rid, String xid) {
        String deviceId = xid.substring(0, 16);
        String sourceId = xid.substring(16);
        StringBuilder buffer = new StringBuilder(addPairForGM);
        buffer.append("?deviceId=").append(deviceId)
                .append("&sourceId=").append(sourceId)
                .append("&addRids=").append(rid)
                .append("-1&directStatusCheck=false");
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC GCS AddPair :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GCS AddPair failed:result:{}", responseEntity);
            throw new RpcException("GCS AddPair failed");
        }
        log.info("RPC GCS AddPair :result:{}", responseEntity);

        String body = responseEntity.getBody();


        List<Map<String, String>> list = null;
        try {
            list = JsonUtil.toObject(body, List.class);
        } catch (IOException e) {
            log.error("GCS AddPair parse json result failed rid:[{}] xid:[{}] body:[{}]", rid, xid, body);
            return ResultUtil.error("104", "Parse json failed");
        }
        if (CollectionUtils.isEmpty(list)) {
            return ResultUtil.error("105", "GCS no result");
        }
        Map<String, String> map = list.get(0);
        String errorCode = map.get("resultCode");
        if (StringUtils.isBlank(errorCode)) {
            log.error("GCS AddPair failed errorCode is null rid:[{}] xid:[{}] body:[{}]", rid, xid, body);
            return ResultUtil.error("101", "GetSession result not exist errorCode", body);
        }
        if (!StringUtils.equalsIgnoreCase("0x0", errorCode)) {
            log.error("GCS AddPair failed errorCode != 0x0 rid:[{}] xid:[{}] body:[{}]", rid, xid, body);
            return ResultUtil.error("102", "GetSession failed", body);
        }
        String data = map.get("data");
        if (StringUtils.isBlank(data)) {
            log.error("GCS AddPair failed session is null rid:[{}] xid:[{}] body:[{}]", rid, xid, body);
            return ResultUtil.error("103", "GetSession session null", body);
        }
        return ResultUtil.success(data);
    }

    @Override
    public Result<String> removePairFromGCS(int pairId) {
        StringBuilder buffer = new StringBuilder(removePairForGM);
        buffer.append("?pairId=").append(pairId);
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC GCS RemovePair :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GCS RemovePair failed:result:{}", responseEntity);
            throw new RpcException("GCS RemovePair failed");
        }
        log.info("RPC GCS RemovePair :result:{}", responseEntity);

        String body = responseEntity.getBody();


        List<Map<String, String>> list = null;
        try {
            list = JsonUtil.toObject(body, List.class);
        } catch (IOException e) {
            log.error("GCS RemovePair parse json result failed pairId:[{}] body:[{}]", pairId, body);
            return ResultUtil.error("104", "Parse json failed");
        }
        if (CollectionUtils.isEmpty(list)) {
            return ResultUtil.error("105", "GCS no result");
        }
        Map<String, String> map = list.get(0);
        String errorCode = map.get("resultCode");
        if (StringUtils.isBlank(errorCode)) {
            log.error("GCS RemovePair failed errorCode is null pairId:[{}] body:[{}]", pairId, body);
            return ResultUtil.error("101", "GetSession result not exist errorCode", body);
        }
        if (!StringUtils.equalsIgnoreCase("0x0", errorCode)) {
            log.error("GCS RemovePair failed errorCode != 0x0 pairId:[{}] body:[{}]", pairId, body);
            return ResultUtil.error("102", "GetSession failed", body);
        }
        return ResultUtil.success();
    }

    @Override
    public boolean isRPairXFromGCS(String rid, String xid) {
        if (xid.length() == 32) {
            xid = xid.substring(0, 16);
        }
        StringBuilder buffer = new StringBuilder(getGridSourceByRidForGM);
        buffer.append("?rid=").append(rid).append("&condition=").append(xid);
        String url = buffer.toString();
        if (!url.startsWith("http")) {
            url = "http://" + url;
        }
        log.info("RPC GCS GetGridSourceByRidForGM :url:{}", url);
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
        if (responseEntity.getStatusCodeValue() != 200) {
            log.error("RPC GCS GetGridSourceByRidForGM failed:result:{}", responseEntity);
            throw new RpcException("GCS GetGridSourceByRidForGM failed");
        }
        log.info("RPC GCS GetGridSourceByRidForGM :result:{}", responseEntity);

        try {
            String body = responseEntity.getBody();
            JsonNode jsonNode = MyUtil.MAPPER.readTree(body);
            if (!jsonNode.has("result")) {
                log.error("GCS GetGridSourceByRidForGM result error rid:[{}] xid:[{}] body:[{}]", rid, xid, body);
                return false;
            }
            int size = jsonNode.get("result").size();
            return size > 0;
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        return false;
    }

    private String parseUserRole(String protocolXML) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document doc = builder
                    .parse(new InputSource(new StringReader(protocolXML)));

            Element root = doc.getDocumentElement();
            NodeList books = root.getChildNodes();
            if (books != null) {
                for (int i = 0; i < books.getLength(); i++) {
                    Node book = books.item(i);
                    String role = book.getFirstChild().getNodeValue();
                    if (role != null) {
                        return role;
                    }
                }
            }
        } catch (ParserConfigurationException e) {
            log.error("Parse xml failed---》" + e);
            log.error("msg:{},e:{}",e.getMessage(),e);
        } catch (SAXException e) {
            log.error("Parse xml failed---》" + e);
            log.error("msg:{},e:{}",e.getMessage(),e);
        } catch (IOException e) {
            log.error("Parse xml failed---》" + e);
            log.error("msg:{},e:{}",e.getMessage(),e);
        }

        return "-1";
    }

}
